<?php
namespace PsiFramework\Classes\Util\Object;

import("Classes.Model.ModelInterface.IPrimitiveObject");
import("Classes.Util.Database.Query.SqlType");

use \PsiFramework\Classes\Util\Database\Query\SqlType;
use \PsiFramework\Classes\Model\ModelInterface\IPrimitiveObject;

/**
 * PsiFramework
 * Php Simple Framework
 *
 * @author Rémi San
 * @version beta
 */

/**
 * The File class represents a file uploaded to the server
 *
 * @package Util.Object
 */
class File implements IPrimitiveObject
{

    protected /*string*/ $_name ;
    protected /*string*/ $_path ;
    protected /*string*/ $_mimeType ;
    protected /*string*/ $_extension ;
    
    protected static $_pbpvar = '[psiframeworkbasepath]'; 

    /**
     * Constructor
     *
     * @param     string    $name        the name of the file
     * @param     string    $path        the path where the file is
     * @param     string    $mimeType    the mimetype of the file
     * @return    File    instance
     */
    public function __construct(
        /*string*/ $name=null,
        /*string*/ $path=null,
        /*string*/ $mimeType=null
    )
    {
        $this->_name = $name ;
        $this->_path = $path ;
        $this->_mimeType = $mimeType ;
        
        $this->initExtension();
    }

    /**
     * Getter for the member variable $name
     *
     * @return string    the name of the file
     */
    public function getName()
    {
        return $this->_name ;
    }

    /**
     * Setter for the member variable $name
     *
     * @param string    $name    the name
     */
    public function setName(/*string*/ $name)
    {
        $this->_name = $name ;
    }

    /**
     * Getter for the member variable $path
     *
     * @return string    the path of the file
     */
    public function getPath()
    {
        return $this->_path ;
    }

    /**
     * Setter for the member variable $path
     *
     * @param string    $path    the path to the file
     */
    public function setPath(/*string*/ $path)
    {
        $this->_path = $path ;
    }

    /**
     * Getter for the member variable $mimeType
     *
     * @return string    the MIME Type of the file
     */
    public function getMimeType()
    {
        return $this->_mimeType ;
    }

    /**
     * Setter for the member variable $mimeType
     *
     * @param string    $mimeType    the MIME type of the file
     */
    public function setMimeType(/*string*/ $mimeType)
    {
        $this->_mimeType = $mimeType ;
    }

    /**
     * Getter for the member variable $extension
     *
     * @return string    the extension of the file
     */
    public function getExtension()
    {
        return $this->_extension ;
    }

    /**
     * Setter for the member variable $extension
     *
     * @param string    $extension    the extension
     */
    public function setExtension(/*string*/ $extension)
    {
        $this->_extension = $extension ;
    }

    public function getFileLink(/*string*/ $subdirectory=null)
    {
        if (isNullOrEmptyString($subdirectory) || startsWith($this->_path, 'http')) {
            return $this->_path;
        } else {
            return $this->getFileDirectory().$subdirectory.'/'.$this->_name;
        }
    }
    
    public function getFileDirectory()
    {
        return str_replace($this->_name, '', $this->_path);
    }

    /**
     * Move the file to the new specified path
     *
     * @param string    $newPath    the path to move the file to
     */
    public function moveTo(/*string*/ $newPath)
    {
        $newname = utf8_encode($this->_name);
        $newPath = $newPath.'/'.$newname;
        
        $ok = move_uploaded_file($this->getFileLink(), $newPath);
        
        $this->_name = $newname;
        $this->_path = $newPath;
        
        return $ok;
    }
    
    public function delete()
    {
        if (!startsWith($this->_path, 'http')) { 
            unlink($this->_path);
        }
    }

    private function initExtension()
    {
        if (!isNullOrEmptyString($this->_name)) {
        	$parts = explode(".", $this->_name);
        	$this->_extension = strtolower($parts[count($parts)-1]);
        	
        	if (!startsWith($this->_path, 'http')) {
        	    $finfo = new \finfo(FILEINFO_MIME_TYPE);
        	    $this->_mimeType = $finfo->file($this->_path);
        	} else {
        	    $this->_mimeType = self::getMimeTypeFromExtension($this->_extension);
        	}
        } else {
            $this->_extension = null;
        }
        
        return $this->_extension;
    }
    
    public function serialize(/*boolean*/ $asText=true)
    {
        $baseDirectoryPath = getBaseDirectory();
        return str_replace($baseDirectoryPath, self::$_pbpvar, $this->getFileLink());
    }

    public function unserialize(/*string*/ $text)
    {
        if (!isNullOrEmptyString($text)) {
            
            if (strstr($text, self::$_pbpvar)!=false) {
                $baseDirectoryPath = getBaseDirectory();
                $text = str_replace(self::$_pbpvar, $baseDirectoryPath, $text);
            }
            
            if (startsWith($text, 'http')) {
                $this->retrieveFromUri($text);
            } else if (file_exists($text)) {
                $this->retrieveFromLocalPath($text);
            }
        }
    }
    
    public function retrieveFromLocalPath(/*string*/ $path)
    {
        $this->_path = $path;
        $this->_name = basename($this->_path);
        $this->initExtension();
    }
    
    public function retrieveFromUri(/*string*/ $uri)
    {
        $this->_path = $uri;
        $this->_name = getUriBaseName($this->_path);
        $this->initExtension();
    }

    public function isEmpty()
    {
        return isNullOrEmptyString($this->_path);
    }
    
    public function toString()
    {
        return $this->getFileLink();
    }

    public static function getSqlType()
    {
        return SqlType::$varchar ;
    }

    public static function getMimeTypeFromExtension(/*string*/ $ext)
    {
        $mimeType = 'application/octet-stream';
        $extType = array(
            'gif'=>'image/gif',
            'jpg'=>'image/jpeg',
            'jpeg'=>'image/jpeg',
            'png'=>'image/png',
            'tiff'=>'image/tiff',
            'ico'=>'image/vnd.microsoft.icon',
            'svg'=>'image/svg+xml',
            'ogg'=>'application/ogg',
            'pdf'=>'application/pdf',
            'xhtml'=>'application/xhtml+xml',
            'swf'=>'application/x-shockwave-flash',
            'json'=>'application/json',
            'js'=>'application/javascript',
            'xml'=>'application/xml',
            'zip'=>'application/zip',
            'mp3'=>'audio/mpeg',
            'wma'=>'audio/x-ms-wma',
            'rm'=>'audio/vnd.rn-realaudio',
            'wav'=>'audio/x-wav',
            'css'=>'text/css',
            'csv'=>'text/csv',
            'htm'=>'text/html',
            'html'=>'text/html',
            'txt'=>'text/plain',
            'xml'=>'text/xml',
            'mpg'=>'video/mpeg',
            'mpeg'=>'video/mpeg',
            'mp4'=>'video/mp4',
            'mov'=>'video/quicktime',
            'wmv'=>'video/x-ms-wmv',
            'avi'=>'video/x-msvideo',
            'flv'=>'video/x-flv'
        );
        
        if (array_key_exists($ext, $extType)) {
            $mimeType = $extType[$ext];
        }
        
        return $mimeType;
    }
    
}
